/*
 * Copyright 2021 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "powermanagercontrol.h"
#include "error.h"

PowerManagerControl::PowerManagerControl(QObject *parent)
    : QObject(parent)
    , m_iface(new QDBusInterface(
          POWER_MANAGEMENT_SERVICE,
          POWER_MANAGEMENT_PATH,
          POWER_MANAGEMENT_INTERFACE_NAME,
          QDBusConnection::systemBus()))
{
    qDebug() << "init power manager control";
}

PowerManagerControl::~PowerManagerControl() {}

void PowerManagerControl::dealControlAction(const QString type, const QVariant data)
{
    qDebug() << "upcoming action type :" << type << "value :" << data;
    if (!type.compare(SUSPEND, Qt::CaseInsensitive)) {
        controlAction(SUSPEND, data.toBool());
    } else if (!type.compare(HIBERNATE, Qt::CaseInsensitive)) {
        controlAction(HIBERNATE, data.toBool());
    } else if (!type.compare(POWER_OFF, Qt::CaseInsensitive)) {
        controlAction(POWER_OFF, data.toBool());
    } else if (!type.compare(TURN_OFF_DISPLAY)) {
        controlDisplay("off");
        turnOffDisplaySignal();
    } else if (!type.compare(TURN_ON_DISPLAY)) {
        controlDisplay("on");
    } else if (!type.compare(POWER_POLICY_AC) || !type.compare(POWER_POLICY_BATTERY)) {
        controlAction(CPU_FREQENCY_MODULATION, data.toInt());
        controlAction(GPU_FREQENCY_MODULATION, data.toInt());
    }
}

int PowerManagerControl::getBrightness()
{
    QDBusReply<int> reply = m_iface->call(GET_BRIGHTNESS);
    if (reply.isValid()) {
        return reply.value();
    } else {
        qCritical() << "error code: " << INIT_BRIGHTNESS_ERROR;
        return 0;
    }
}

void PowerManagerControl::setBrigtness(const int value)
{
    controlAction(REGULATE_BRIGHTNESS, value);
}

void PowerManagerControl::setConfigValue(const QString type, const QVariant value)
{
    QDBusVariant v1;
    QVariant v2;
    v1.setVariant(value);
    v2.setValue(v1);
    controlAction(SET_POWER_CONFIG, type, v2);
}

void PowerManagerControl::controlDisplay(QString state)
{
    if ("wayland" == qgetenv("XDG_SESSION_TYPE")) {
        executeLinuxCmd(QString("export QT_QPA_PLATFORM=wayland && kscreen-doctor --dpms %1").arg(state));
    } else {
        executeLinuxCmd(QString("xset dpms force %1").arg(state));
    }
}

void PowerManagerControl::turnOffDisplaySignal()
{
    const bool state = true;
    QDBusMessage msg = QDBusMessage::createSignal("/", "ukui.power.manager", "TurnOffDisplay");
    msg << state;
    QDBusConnection::sessionBus().send(msg);
    qDebug() << "send turn off display msg";
}

QString PowerManagerControl::executeLinuxCmd(const QString strCmd)
{
    QProcess process;
    process.start("bash", QStringList() << "-c" << strCmd);
    process.waitForFinished();
    QString strResult = process.readAllStandardOutput() + process.readAllStandardError();
    return strResult;
}

template <typename key, typename value>
void PowerManagerControl::controlAction(const key &type, const value &data)
{
    m_iface->call(type, data);
}

template <typename key, typename value, typename value1>
void PowerManagerControl::controlAction(const key &type, const value &data, const value1 &data1)
{
    m_iface->call(type, data, data1);
}
